﻿Imports BE.BE
Imports BL.BL

Public Class frmGestionUsuarios


#Region "Atributos"

    Dim mTipoGrabar As Integer

    'seguridad usr-familia-patente.
    Enum Permisos
        Denegado = 0
        Permitido = 1
    End Enum

    Dim listaFamiliasAsociadasUsuario As New List(Of Familia_BE)
    Dim listaFamiliasDisponibles As New List(Of Familia_BE)

    Dim listaPatentesAsociadasUsuarioHeredadasPorFamilia As New List(Of Patente_BE)
    Dim listaPatentesAsociadasUsuarioOtorgadas As New List(Of Patente_BE)
    Dim listaPatentesAsociadasUsuario As New List(Of Patente_BE)

    Dim listaPatentesDisponibles As New List(Of Patente_BE)
    Dim mOcultar As Boolean = True

#End Region


#Region "Métodos"

    'load.
    Private Sub frmGestionUsuarios_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        'idiomas.
        cbIdioma.Items.Add("castellano")
        cbIdioma.Items.Add("ingles")
        'cbIdioma.Items.Add("portugues")
        'grilla Usuarios.
        With Me.dgvUsuarios
            .SelectionMode = DataGridViewSelectionMode.FullRowSelect
            .AutoGenerateColumns = False
            .Columns.Add("c0", "id")
            .Columns(0).DataPropertyName = "id"
            .Columns(0).Width = 20
            .Columns(0).Visible = False
            .Columns.Add("c1", "ididioma")
            .Columns(1).DataPropertyName = "ididioma"
            .Columns(1).Width = 20
            .Columns(1).Visible = False
            .Columns.Add("c2", "nombre")
            .Columns(2).DataPropertyName = "nombre"
            .Columns(2).Width = 120
            .Columns(2).Visible = False
            .Columns.Add("c3", "apellido")
            .Columns(3).DataPropertyName = "apellido"
            .Columns(3).Width = 110
            .Columns(3).Visible = False
            .Columns.Add("c4", "usuario")
            .Columns(4).DataPropertyName = "nick"
            .Columns(4).Width = 90
            .Columns(4).Visible = True
            .Columns.Add("c5", "password")
            .Columns(5).DataPropertyName = "password"
            .Columns(5).Width = 150
            .Columns(5).Visible = False
            .Columns.Add("c6", "bloqueado")
            .Columns(6).DataPropertyName = "bloqueado"
            .Columns(6).Width = 20
            .Columns(6).Visible = False
            .Columns.Add("c7", "intentos_inc")
            .Columns(7).DataPropertyName = "intentosfallidos"
            .Columns(7).Width = 20
            .Columns(7).Visible = False
            .Columns.Add("c8", "password_reset")
            .Columns(8).DataPropertyName = "passwordreset"
            .Columns(8).Width = 20
            .Columns(8).Visible = False
            .DataSource = Usuario_BL.listar
        End With
        'nos paramos en el primero, asi completamos los txtbox de la derecha.
        GrillaUsuarios_Click(Nothing, Nothing)

        'cosmetica.
        Me.gbDatosUsuario.Text = "Datos del usuario seleccionado"
        Me.chbBloqueado.Enabled = False
        Me.txtUsuario.ReadOnly = True
        Me.txtNombre.ReadOnly = True
        Me.txtApellido.ReadOnly = True
        Me.cbIdioma.Enabled = False
        Me.cbIdioma.DropDownStyle = ComboBoxStyle.DropDownList
        Me.lbClave.Visible = False
        Me.btnBlanquearClave.Visible = False
        Me.btnGrabar.Visible = False
        Me.btnCancelarGrabar.Visible = False

        'çontroles para el control de indices.
        Me.lbID.Visible = False
        Me.lbIntentosInc.Visible = False
        Me.chbClaveBlanqueada.Visible = False

        'seguridad usr-familia-patente.
        Me.gbFamilias.Visible = False
        Me.gbPatentes.Visible = False
        Me.lbMensajeFamiliasPatentes.Visible = False

        'combobox para permitir/negar patente.
        cbPatentePermitidaNegada.Items.Add(Permisos.Denegado)
        cbPatentePermitidaNegada.Items.Add(Permisos.Permitido)
        cbPatentePermitidaNegada.SelectedIndex = 1

        'formato d elas datagridview de familias y patentes.
        Me.dgvFamiliasAsociadas.AutoGenerateColumns = False
        Me.dgvFamiliasAsociadas.Columns.Clear()
        Me.dgvFamiliasAsociadas.SelectionMode = DataGridViewSelectionMode.FullRowSelect
        Me.dgvFamiliasDisponibles.AutoGenerateColumns = False
        Me.dgvFamiliasDisponibles.Columns.Clear()
        Me.dgvFamiliasDisponibles.SelectionMode = DataGridViewSelectionMode.FullRowSelect
        Me.dgvPatentesAsociadas.AutoGenerateColumns = False
        Me.dgvPatentesAsociadas.Columns.Clear()
        Me.dgvPatentesAsociadas.SelectionMode = DataGridViewSelectionMode.FullRowSelect
        Me.dgvPatentesDisponibles.AutoGenerateColumns = False
        Me.dgvFamiliasDisponibles.Columns.Clear()
        Me.dgvFamiliasDisponibles.SelectionMode = DataGridViewSelectionMode.FullRowSelect

        'GroupBox Familias:
        With Me.dgvFamiliasAsociadas
            .Columns.Add("c0", "id_familia")
            .Columns(0).DataPropertyName = "Id"
            .Columns(0).Width = 20
            .Columns(0).Visible = False
            .Columns.Add("c1", "nombre")
            .Columns(1).DataPropertyName = "Nombre"
            .Columns(1).Width = 200
            .Columns(1).Visible = True
            .Columns.Add("c2", "descripción")
            .Columns(2).DataPropertyName = "Descripcion"
            .Columns(2).Width = 100
            .Columns(2).Visible = False
        End With
        With Me.dgvFamiliasDisponibles
            .Columns.Add("c0", "id_familia")
            .Columns(0).DataPropertyName = "Id"
            .Columns(0).Width = 20
            .Columns(0).Visible = False
            .Columns.Add("c1", "nombre")
            .Columns(1).DataPropertyName = "Nombre"
            .Columns(1).Width = 200
            .Columns(1).Visible = True
            .Columns.Add("c2", "descripción")
            .Columns(2).DataPropertyName = "Descripcion"
            .Columns(2).Width = 100
            .Columns(2).Visible = False
        End With

        'GroupBox Patentes.
        With Me.dgvPatentesAsociadas
            .Columns.Add("c0", "id_patente")
            .Columns(0).DataPropertyName = "Id"
            .Columns(0).Width = 20
            .Columns(0).Visible = False
            .Columns.Add("c1", "tipo")
            .Columns(1).DataPropertyName = "Tipo"
            .Columns(1).Width = 12
            .Columns(1).Visible = True
            .Columns.Add("c2", "nombre")
            .Columns(2).DataPropertyName = "Nombre"
            .Columns(2).Width = 188
            .Columns(2).Visible = True
            .Columns.Add("c3", "descripción")
            .Columns(3).DataPropertyName = "Descripcion"
            .Columns(3).Width = 100
            .Columns(3).Visible = False
        End With
        With Me.dgvPatentesDisponibles
            .Columns.Add("c0", "id_patente")
            .Columns(0).DataPropertyName = "Id"
            .Columns(0).Width = 20
            .Columns(0).Visible = False
            .Columns.Add("c1", "nombre")
            .Columns(1).DataPropertyName = "Nombre"
            .Columns(1).Width = 200
            .Columns(1).Visible = True
            .Columns.Add("c2", "descripción")
            .Columns(2).DataPropertyName = "Descripcion"
            .Columns(2).Width = 100
            .Columns(2).Visible = False
            .Columns.Add("c3", "tipo")
            .Columns(3).DataPropertyName = "Tipo"
            .Columns(3).Width = 80
            .Columns(3).Visible = False
        End With

        'si hay falla de integridad de BD (tablas usuario_familia ó usuario_patente) - no seteamos patentes
        If frmPrincipal.integridad = True And frmPrincipal.usr.nick <> "suseas" Then
            'patentes del usuario logueado.
            Helper_FL.setearPermisos(frmPrincipal.usr, Me)
        End If

    End Sub


    'nuevo usuario (no se asignan familias ni patentes al crearlo).. es por un tema de referencias al id_usuario (hasta que no se graba no lo obtenemos).
    Private Sub btnNuevo_Click(sender As Object, e As EventArgs) Handles btnNuevo.Click
        'çosmetica
        mTipoGrabar = 1
        Me.gbDatosUsuario.Text = "Datos del nuevo usuario:"
        Me.btnNuevo.Visible = False
        Me.btnModificar.Visible = False
        Me.btnEliminar.Visible = False
        Me.btnVerFamiliasPatentesUsuario.Visible = False
        Me.chbBloqueado.Enabled = True
        Me.chbBloqueado.CheckState = False
        Me.txtNombre.ReadOnly = False
        Me.txtNombre.Text = ""
        Me.txtApellido.ReadOnly = False
        Me.txtApellido.Text = ""
        Me.txtUsuario.ReadOnly = False
        Me.txtUsuario.Text = ""
        Me.cbIdioma.Enabled = True
        Me.cbIdioma.SelectedValue = 0
        Me.lbClave.Visible = False
        Me.btnBlanquearClave.Visible = False
        Me.btnGrabar.Visible = True
        Me.btnCancelarGrabar.Visible = True
        Me.lbMensajeFamiliasPatentes.Visible = True

        'evito que se pueda seleccionar otro usuario y que se cambien los datos de los textbox.
        RemoveHandler dgvUsuarios.Click, AddressOf GrillaUsuarios_Click


    End Sub


    'modificar usuario.
    Private Sub btnModificar_Click(sender As Object, e As EventArgs) Handles btnModificar.Click
        mTipoGrabar = 2

        'No se puede modificar el nick.
        'cosmetica
        Me.gbListaUsuarios.Visible = False
        Me.gbFamilias.Visible = True
        Me.gbPatentes.Visible = True
        Me.gbDatosUsuario.Text = "Datos a modificar del usuario seleccionado:"
        Me.btnGrabar.Visible = True
        Me.btnCancelarGrabar.Visible = True

        'no se puede bloquear el nick suseas.
        If Me.txtUsuario.Text = "suseas" Then
            'usr suseas.
            Me.chbBloqueado.Enabled = False
        Else
            'cualquier usr.
            Me.chbBloqueado.Enabled = True
        End If
        Me.txtNombre.ReadOnly = False
        Me.txtApellido.ReadOnly = False
        Me.txtUsuario.ReadOnly = True
        Me.cbIdioma.Enabled = True
        Me.lbClave.Visible = True
        Me.btnBlanquearClave.Visible = True
        Me.lbAvisoPatentesNegadasOtorgadas.Visible = True

        'FAMILIAS. 
        'a medida que asocie familias al usuario, me llenará las lista de patentes asociadas y disponibles.
        Me.listaFamiliasAsociadasUsuario = Familia_BL.listarFamiliasPorUsuario(CInt(Me.lbID.Text))

        'calculamos a partir de las familias asociadas, la lista de familias disponibles.
        listaFamiliasDisponibles = Familia_BL.listarFamilias()
        'quitamos las ya asignadas al usuario.
        For Each fam1 As Familia_BE In listaFamiliasAsociadasUsuario
            For Each fam2 As Familia_BE In listaFamiliasDisponibles
                If fam1.Id = fam2.Id Then
                    listaFamiliasDisponibles.Remove(fam2)
                    Exit For
                End If
            Next
        Next

        'PATENTES ASOCIADAS.
        Dim existe As Boolean
        Dim listaPatentesDeLaFamilia As New List(Of Patente_BE)
        listaPatentesAsociadasUsuarioHeredadasPorFamilia.Clear()
        'recorro las patentes de la familia asociada, si ya la tengo en mi lista de patentes asociadas heredadas por familia la descarto.
        For Each familia As Familia_BE In listaFamiliasAsociadasUsuario
            'recorro de a una familia y tomo todas sus patentes.
            listaPatentesDeLaFamilia = Familia_BL.listarPatentesDeLaFamilia(familia.Id)
            'cada una de las patentes de la familia asociada, la comparo con la que tengo ya cargada en mi lista de patentes asociadas heredadas por familia.
            For Each pat1 As Patente_BE In listaPatentesDeLaFamilia
                existe = False
                For Each pat2 As Patente_BE In listaPatentesAsociadasUsuarioHeredadasPorFamilia
                    'pregunto si ya esta en la lista de patentes asociadas.
                    If pat1.Id = pat2.Id Then
                        'ya lo tengo -> lo descarto.
                        existe = True
                        Exit For
                    End If
                Next
                'si no la tenia -> la cargo.
                If existe = False Then
                    listaPatentesAsociadasUsuarioHeredadasPorFamilia.Add(pat1)
                End If
            Next
        Next

        'PATENTES DISPONIBLES.
        'resto a lista de todas las patentes del sistema, las que tengo heredadas por familia (me quedarán disponibles para asociar en algún momento).
        listaPatentesDisponibles = Patente_BL.ListarTodasLasPatentes
        For Each pat1 As Patente_BE In listaPatentesAsociadasUsuarioHeredadasPorFamilia
            'pregunto si ya esta en la lista de disponibles.
            For Each pat2 As Patente_BE In listaPatentesDisponibles
                If pat1.Id = pat2.Id Then
                    'la tengo asociada-> la descarto de las disponibles.
                    listaPatentesDisponibles.Remove(pat2)
                    Exit For
                End If
            Next
        Next

        'LISTA PATENTES ASOCIADAS DEFINITIVA agregamos las patentes otorgadas y modificamos el permiso de las que ya estan si da el caso..
        'recorremos la relacion usuario-patente para traer las que se asignaron por afuera de una familia.
        listaPatentesAsociadasUsuarioOtorgadas = Usuario_BL.listarPatentesOtorgadas(CInt(Me.lbID.Text))
        listaPatentesAsociadasUsuario = listaPatentesAsociadasUsuarioHeredadasPorFamilia
        'obtenemos la lista de patentes asociadas al usuario definitiva.
        'por cada patente otorgada recorro la lista de patentes heredadas por familia y si no esta la agrego.
        'si ya estaba la patente le fuerzo el estado permitido/denegado que esta dado por la patente otorgada.
        For Each pat1 As Patente_BE In listaPatentesAsociadasUsuarioOtorgadas
            existe = False
            For Each pat2 As Patente_BE In listaPatentesAsociadasUsuarioHeredadasPorFamilia
                If pat1.Id = pat2.Id Then
                    'seteo el estado de la patente otorgada.
                    pat2.Tipo = pat1.Tipo
                    existe = True
                    Exit For
                End If
            Next
            If existe = False Then
                'patente que no estaba heredada por nínguna familia -> la agrego.
                listaPatentesAsociadasUsuario.Add(pat1)
            End If
        Next

        ActualizarGrillasFamiliasPatentes()


    End Sub


    'eliminar usuario (BORRADO LOGICO) no tendremos problemas con las FK..
    Private Sub btnEliminar_Click(sender As Object, e As EventArgs) Handles btnEliminar.Click
        'control de que al menos quede un usuario para administrar el sistema SEAS.
        If Me.txtUsuario.Text = "suseas" Then
            MessageBox.Show("El sistema no admite borrar el usuario administrador del sistema..")
            Exit Sub
        End If

        'control para no borrar el usuario que actualmente esté invocando el borrado de registros.
        'If Me.txtUsuario.Text = frmlogin.nickensesion.ToString Then
        If Me.txtUsuario.Text = frmPrincipal.usr.nick.ToString Then
            MessageBox.Show("El sistema no admite borrar el usuario que actualmente realiza sesión..")
            Exit Sub
        End If

        If MsgBox("Se borrará el Usuario: " & Me.txtUsuario.Text & ", Está seguro??", MsgBoxStyle.OkCancel, "Borrado de Usuario") = MsgBoxResult.Ok Then
            Dim usr As New Usuario_BE
            usr.id = CInt(Me.lbID.Text)
            Usuario_BL.baja(usr)

            'grabar en bitácora.
            Dim mov As New TipoMovimiento_BE
            mov.mDescripcion = "se eliminó un usuario"
            mov.mCriticidad = 1
            Bitacora_BL.grabarEnBitacora(usr, mov)

            'cosmetica.
            Me.dgvUsuarios.DataSource = Usuario_BL.listar
            GrillaUsuarios_Click(Nothing, Nothing)
        End If

    End Sub


    'ver familias patentes del usuario seleccionado.
    Private Sub btnVerFamiliasPatentesUsuario_Click(sender As Object, e As EventArgs) Handles btnVerFamiliasPatentesUsuario.Click
        If mOcultar = True Then
            mOcultar = False
            'cosmetica. (queda sólo el botón Ocultar visible).
            Me.btnVerFamiliasPatentesUsuario.Text = "Ocultar"
            Me.dgvUsuarios.Visible = False
            Me.btnNuevo.Visible = False
            Me.btnModificar.Visible = False
            Me.btnEliminar.Visible = False
            Me.gbFamilias.Visible = True
            Me.gbPatentes.Visible = True

            Me.lbFamiliasDisponibles.Visible = False
            Me.dgvFamiliasDisponibles.Visible = False
            Me.btnAsociarFamilia.Visible = False
            Me.btnDesasociarFamilia.Visible = False

            Me.lbPatentesDisponibles.Visible = False
            Me.dgvPatentesDisponibles.Visible = False
            Me.btnAsociarPatente.Visible = False
            Me.btnDesasociarPatente.Visible = False

            Me.lbPermisoDeLaPatente.Visible = False
            Me.cbPatentePermitidaNegada.Visible = False
            Me.btnCambiarEstadoPermiso.Visible = False

            'FAMILIAS.
            Me.listaFamiliasAsociadasUsuario = Familia_BL.listarFamiliasPorUsuario(CInt(Me.lbID.Text))

            'PATENTES.
            Dim existe As Boolean
            listaPatentesAsociadasUsuarioHeredadasPorFamilia.Clear()
            'recorro todas las familias y filtro las patentes para quedarme con las que no se repiten.
            For Each fam As Familia_BE In listaFamiliasAsociadasUsuario
                Dim listaPatentesAsociadasFamilia As New List(Of Patente_BE)
                listaPatentesAsociadasFamilia = Familia_BL.listarPatentesDeLaFamilia(fam.Id)
                'tomo de a una patente de la familia asociada.
                For Each pat1 As Patente_BE In listaPatentesAsociadasFamilia
                    existe = False
                    'la comparo con cada una de las patentes de mi lista de patentes asociadas heredadas por familias.
                    For Each pat2 As Patente_BE In listaPatentesAsociadasUsuarioHeredadasPorFamilia
                        If pat1.Id = pat2.Id Then
                            'la tengo ya en mi lista de patentes asociadas -> la descarto.
                            existe = True
                            Exit For
                        End If
                    Next
                    If existe = False Then
                        'no está la patente en mi lista de patentes asociadas heredadas por familias -> la grabo.
                        Dim pat As New Patente_BE
                        pat.Id = pat1.Id
                        pat.Nombre = pat1.Nombre
                        pat.Descripcion = pat1.Descripcion
                        pat.Tipo = pat1.Tipo
                        listaPatentesAsociadasUsuarioHeredadasPorFamilia.Add(pat)
                    End If
                Next
            Next

            'LISTA PATENTES ASOCIADAS DEFINITIVA agregamos las Otorgadas y modificamos el permiso de las que ya estan si da el caso..
            'recorremos la relacion usuario-patente para traer las que se asignaron por afuera de una familia.
            listaPatentesAsociadasUsuarioOtorgadas = Usuario_BL.listarPatentesOtorgadas(CInt(Me.lbID.Text))
            listaPatentesAsociadasUsuario = listaPatentesAsociadasUsuarioHeredadasPorFamilia
            'obtenemos la lista de patentes asociadas al usuario definitiva.
            'por cada patente otorgada recorro la lista de patentes heredadas por familia y si no esta la agrego.
            'si ya estaba la patente le fuerzo el estado permitido/denegado que esta dado por la patente otorgada.
            For Each pat1 As Patente_BE In listaPatentesAsociadasUsuarioOtorgadas
                existe = False
                For Each pat2 As Patente_BE In listaPatentesAsociadasUsuarioHeredadasPorFamilia
                    If pat1.Id = pat2.Id Then
                        'seteo el estado de la patente otorgada.
                        pat2.Tipo = pat1.Tipo
                        existe = True
                        Exit For
                    End If
                Next
                If existe = False Then
                    'patente que no estaba heredada por nínguna familia -> la agrego.
                    listaPatentesAsociadasUsuario.Add(pat1)
                End If
            Next

            ActualizarGrillasPatentes()

        Else
            mOcultar = True
            'cosmetica. 
            Me.btnVerFamiliasPatentesUsuario.Text = "Ver Familias Patentes"
            Me.dgvUsuarios.Visible = True
            Me.btnNuevo.Visible = True
            Me.btnModificar.Visible = True
            Me.btnEliminar.Visible = True
            Me.gbFamilias.Visible = False
            Me.gbPatentes.Visible = False
            Me.lbFamiliasDisponibles.Visible = True
            Me.dgvFamiliasDisponibles.Visible = True
            Me.btnAsociarFamilia.Visible = True
            Me.btnDesasociarFamilia.Visible = True
            Me.lbPatentesDisponibles.Visible = True
            Me.dgvPatentesDisponibles.Visible = True
            Me.btnAsociarPatente.Visible = True
            Me.btnDesasociarPatente.Visible = True
            Me.lbPermisoDeLaPatente.Visible = True
            Me.cbPatentePermitidaNegada.Visible = True
            Me.btnCambiarEstadoPermiso.Visible = True

        End If

    End Sub


    'blanquear clave.
    Private Sub btnBlanquearPassword_Click(sender As Object, e As EventArgs) Handles btnBlanquearClave.Click
        If MsgBox("Atención.. Blanqueará la clave del usuario seleccionado.. Está seguro?", 1, "Atención") = MsgBoxResult.Ok Then
            'generar password aleatorio para copiar y enviar por email al usuario que pidió el blanqueo.
            Me.chbClaveBlanqueada.CheckState = CheckState.Checked
            Dim newpassword As String = Helper_BL.generarCadenaAleatoria(10)
            Usuario_BL.blanquearPassword(CInt(Me.lbID.Text), newpassword)
            frmNuevaClave.nuevaClave = newpassword
            frmNuevaClave.Show()
        End If
    End Sub


    'grabar.
    Private Sub btnGrabar_Click(sender As Object, e As EventArgs) Handles btnGrabar.Click

        Dim usr As New Usuario_BE
        Dim mov As New TipoMovimiento_BE
        usr.ididioma = Me.cbIdioma.SelectedIndex
        usr.bloqueado = Me.chbBloqueado.CheckState
        usr.nick = Me.txtUsuario.Text
        usr.nombre = Me.txtNombre.Text
        usr.apellido = Me.txtApellido.Text


        Select Case mTipoGrabar

            Case 1 'nuevo
                'se consultara a la BD el nuevo nick para evitar duplicados.
                If Usuario_BL.traerUsuario(Me.txtUsuario.Text) Is Nothing Then
                    'password blanqueado por defecto
                    Dim newpassword As String = Helper_BL.generarCadenaAleatoria(10)
                    frmNuevaClave.nuevaClave = newpassword
                    usr.password = Helper_BL.encriptarMD5(newpassword)
                    usr.intentosfallidos = 0
                    usr.passwordreset = True
                    'seguridad.
                    ''por un tema de integridad referencial, no se graba en Nuevo las familias/patentes.
                    Usuario_BL.alta(usr)

                    'acualizamos el id_usuario del nuevo.
                    usr.id = (Usuario_BL.traerUsuario(Me.txtUsuario.Text)).id
                    'grabar en bitácora.
                    mov.mDescripcion = "se creó nuevo usuario"
                    mov.mCriticidad = 1
                    Bitacora_BL.grabarEnBitacora(usr, mov)

                    frmNuevaClave.ShowDialog()

                Else
                    MessageBox.Show("El Usuario ingresado ya existe..")
                    Me.txtUsuario.Focus()
                    Exit Sub
                End If

            Case 2 'desbloqueado/modificación de campos
                'se modificaron campos
                usr.id = CInt(lbID.Text)
                usr.intentosfallidos = CInt(Me.lbIntentosInc.Text)
                usr.passwordreset = chbClaveBlanqueada.CheckState

                'verificamos si además se desbloqueo (es una modifiación).
                Dim usr2 As New Usuario_BE
                usr2 = Usuario_BL.traerUsuario(Me.txtUsuario.Text)

                If usr2.bloqueado = True And Me.chbBloqueado.CheckState = CheckState.Unchecked Then
                    'lo desbloqueamos en la BD.
                    Usuario_BL.desbloquearUsuario(usr.id)
                    usr.intentosfallidos = 0
                End If

                'seguridad.
                usr.Familias = listaFamiliasAsociadasUsuario
                'las patentes otorgads ya se persitieron.

                'grabar en bitácora.
                mov.mDescripcion = "se modificó un usuario"
                mov.mCriticidad = 1
                Bitacora_BL.grabarEnBitacora(usr, mov)

                Usuario_BL.modificar(usr)

                'caso usuario logueado le cambiamos las patentes.
                If usr.id = frmPrincipal.usr.id Then
                    usr.Patentes = listaPatentesAsociadasUsuario
                    frmPrincipal.usr = usr
                End If


        End Select

        'çosmetica
        Me.gbDatosUsuario.Text = "Datos del usuario seleccionado:"
        Me.btnGrabar.Visible = False
        Me.btnCancelarGrabar.Visible = False
        Me.chbBloqueado.Enabled = False
        Me.txtNombre.ReadOnly = True
        Me.txtApellido.ReadOnly = True
        Me.txtUsuario.ReadOnly = True
        Me.cbIdioma.Enabled = False
        Me.lbAvisoPatentesNegadasOtorgadas.Visible = False

        If mTipoGrabar = 1 Then
            Me.btnNuevo.Enabled = True
            Me.btnModificar.Enabled = True
            Me.btnEliminar.Enabled = True
            'habilito nuevamente que se pueda seleccionar un usuario y cargar los texbox con sus datos.
            AddHandler dgvUsuarios.Click, AddressOf GrillaUsuarios_Click
        End If

        If mTipoGrabar = 2 Then
            Me.gbListaUsuarios.Visible = True
            Me.gbFamilias.Visible = False
            Me.gbPatentes.Visible = False
        End If

        Me.dgvUsuarios.DataSource = Usuario_BL.listar
        GrillaUsuarios_Click(Nothing, Nothing)
        Me.dgvUsuarios.Focus()

    End Sub


    'cancelar Grabar.
    Private Sub btnCancelarGrabar_Click(sender As Object, e As EventArgs) Handles btnCancelarGrabar.Click

        If mTipoGrabar = 1 Then
            'NUEVO.
            'habilito nuevamente que se pueda seleccionar un usuario y cargar los texbox con sus datos.
            AddHandler dgvUsuarios.Click, AddressOf GrillaUsuarios_Click

            Me.lbMensajeFamiliasPatentes.Visible = False
            Me.btnNuevo.Visible = True
            Me.btnModificar.Visible = True
            Me.btnEliminar.Visible = True
            Me.btnVerFamiliasPatentesUsuario.Visible = True
        End If

        If mTipoGrabar = 2 Then
            'MODIFICAR.
            Me.gbListaUsuarios.Visible = True
            Me.gbFamilias.Visible = False
            Me.gbPatentes.Visible = False
        End If

        Me.gbDatosUsuario.Text = "Datos del usuario seleccionado:"
        Me.chbBloqueado.Enabled = False
        Me.txtUsuario.ReadOnly = True
        Me.txtNombre.ReadOnly = True
        Me.txtApellido.ReadOnly = True
        Me.txtUsuario.ReadOnly = True
        Me.cbIdioma.Enabled = False
        Me.lbClave.Visible = False
        Me.btnBlanquearClave.Visible = False
        Me.btnGrabar.Visible = False
        Me.btnCancelarGrabar.Visible = False

        'nos paramos en el primero y mostramos los datos en los txtbox.
        GrillaUsuarios_Click(Nothing, Nothing)

    End Sub


    ' << FAMILIA.
    Private Sub btnAsociarFamilia_Click(sender As Object, e As EventArgs) Handles btnAsociarFamilia.Click

        'control dgv vacío.
        If dgvFamiliasDisponibles.RowCount = 0 Then
            MessageBox.Show("No hay Familias disponibles para asociar..")
            Exit Sub
        End If

        'FAMILIAS.
        'asignación detallada.
        Dim fam As New Familia_BE
        fam.Id = dgvFamiliasDisponibles.SelectedRows(0).Cells(0).Value
        fam.Nombre = dgvFamiliasDisponibles.SelectedRows(0).Cells(1).Value.ToString
        fam.Descripcion = dgvFamiliasDisponibles.SelectedRows(0).Cells(2).Value.ToString
        listaFamiliasAsociadasUsuario.Add(fam)
        'lo quito de la otra lista.
        Dim salir As Boolean = False
        For Each fam1 As Familia_BE In listaFamiliasAsociadasUsuario
            For Each fam2 As Familia_BE In listaFamiliasDisponibles
                If fam1.Id = fam2.Id Then
                    listaFamiliasDisponibles.Remove(fam2)
                    salir = True
                    Exit For
                End If
            Next
            If salir = True Then
                Exit For
            End If
        Next


        'PATENTES HEREDADAS.
        Dim existe As Boolean
        Dim listaPatentesDeLaFamilia As New List(Of Patente_BE)
        listaPatentesAsociadasUsuarioHeredadasPorFamilia.Clear()
        'recorro las patentes de la familia asociada, si ya la tengo en mi lista de patentes heredadas por familia la descarto.
        For Each familia As Familia_BE In listaFamiliasAsociadasUsuario
            'recorro de a una familia y tomo todas sus patentes.
            listaPatentesDeLaFamilia = Familia_BL.listarPatentesDeLaFamilia(familia.Id)
            'cada una de las patentes de la familia asociada, la comparo con la que tengo ya cargada en mi lista de patentes asociadas heredadas por familia.
            For Each pat1 As Patente_BE In listaPatentesDeLaFamilia
                existe = False
                For Each pat2 As Patente_BE In listaPatentesAsociadasUsuarioHeredadasPorFamilia
                    'pregunto si ya esta en la lista de patentes asociadas.
                    If pat1.Id = pat2.Id Then
                        'ya lo tengo -> lo descarto.
                        existe = True
                        Exit For
                    End If
                Next
                'si no la tenia -> la cargo.
                If existe = False Then
                    listaPatentesAsociadasUsuarioHeredadasPorFamilia.Add(pat1)
                End If
            Next
        Next

        'LISTA PATENTES ASOCIADAS DEFINITIVA agregamos las patentes otorgadas y modificamos el permiso de las que ya estan si da el caso..
        'recorremos la relacion usuario-patente para traer las que se asignaron por afuera de una familia.
        listaPatentesAsociadasUsuarioOtorgadas = Usuario_BL.listarPatentesOtorgadas(CInt(Me.lbID.Text))
        listaPatentesAsociadasUsuario = listaPatentesAsociadasUsuarioHeredadasPorFamilia
        'obtenemos la lista de patentes asociadas al usuario definitiva.
        'por cada patente otorgada recorro la lista de patentes heredadas por familia y si no esta la agrego.
        'si ya estaba la patente le fuerzo el estado permitido/denegado que esta dado por la patente otorgada.
        For Each pat1 As Patente_BE In listaPatentesAsociadasUsuarioOtorgadas
            existe = False
            For Each pat2 As Patente_BE In listaPatentesAsociadasUsuarioHeredadasPorFamilia
                If pat1.Id = pat2.Id Then
                    'seteo el estado de la patente otorgada.
                    pat2.Tipo = pat1.Tipo
                    existe = True
                    Exit For
                End If
            Next
            If existe = False Then
                'patente que no estaba heredada por nínguna familia -> la agrego.
                listaPatentesAsociadasUsuario.Add(pat1)
            End If
        Next


        'PATENTES DISPONIBLES.
        'resto a lista de todas las patentes del sistema, las que tengo heredadas por familia y otorgadas (nuevas o modifican tipo de las heredadas).
        ' me quedarán disponibles para asociar en algún momento.
        listaPatentesDisponibles = Patente_BL.ListarTodasLasPatentes
        For Each pat1 As Patente_BE In listaPatentesAsociadasUsuario
            'pregunto si ya esta en la lista de disponibles.
            For Each pat2 As Patente_BE In listaPatentesDisponibles
                If pat1.Id = pat2.Id Then
                    'la tengo asociada-> la descarto de las disponibles.
                    listaPatentesDisponibles.Remove(pat2)
                    Exit For
                End If
            Next
        Next

        ActualizarGrillasFamiliasPatentes()

    End Sub


    ' >> FAMILIA.
    Private Sub btnDesasociarFamilia_Click(sender As Object, e As EventArgs) Handles btnDesasociarFamilia.Click

        'control dgv vacío.
        If dgvFamiliasAsociadas.RowCount = 0 Then
            MessageBox.Show("No hay Familias asociadas para quitar..")
            Exit Sub
        End If

        'FAMILIAS.
        'deasignación detallada.
        Dim fam As New Familia_BE
        fam.Id = dgvFamiliasAsociadas.SelectedRows(0).Cells(0).Value
        fam.Nombre = dgvFamiliasAsociadas.SelectedRows(0).Cells(1).Value.ToString
        fam.Descripcion = dgvFamiliasAsociadas.SelectedRows(0).Cells(2).Value.ToString
        listaFamiliasDisponibles.Add(fam)
        'lo quito de la otra lista.
        Dim salir As Boolean = False
        For Each fam1 As Familia_BE In listaFamiliasDisponibles
            For Each fam2 As Familia_BE In listaFamiliasAsociadasUsuario
                If fam1.Id = fam2.Id Then
                    listaFamiliasAsociadasUsuario.Remove(fam2)
                    salir = True
                    Exit For
                End If
            Next
            If salir = True Then
                Exit For
            End If
        Next


        'PATENTES ASOCIADAS.
        'cargo las patentes de la familia asociada, si ya tengo la patente no la vuelvo a asociar.
        Dim existe As Boolean
        Dim listaPatentesDeLaFamilia As New List(Of Patente_BE)
        listaPatentesAsociadasUsuarioHeredadasPorFamilia.Clear()
        For Each familia As Familia_BE In listaFamiliasAsociadasUsuario
            'recorro de a una familia y tomo todas sus patentes.
            listaPatentesDeLaFamilia = Familia_BL.listarPatentesDeLaFamilia(familia.Id)
            'cada una de las patentes de la familia asociada, la comparo con la que tengo ya cargada en mi lista de patentes asociadas al usuario.
            For Each pat1 As Patente_BE In listaPatentesDeLaFamilia
                existe = False
                For Each pat2 As Patente_BE In listaPatentesAsociadasUsuarioHeredadasPorFamilia
                    'pregunto si ya esta en la lista de patentes asociadas.
                    If pat1.Id = pat2.Id Then
                        'ya lo tengo -> lo descarto.
                        existe = True
                        Exit For
                    End If
                Next
                'si no la tenia -> la cargo.
                If existe = False Then
                    listaPatentesAsociadasUsuarioHeredadasPorFamilia.Add(pat1)
                End If
            Next
        Next

        'LISTA PATENTES ASOCIADAS DEFINITIVA agregamos las patentes otorgadas y modificamos el permiso de las que ya estan si da el caso..
        'recorremos la relacion usuario-patente para traer las que se asignaron por afuera de una familia.
        listaPatentesAsociadasUsuarioOtorgadas = Usuario_BL.listarPatentesOtorgadas(CInt(Me.lbID.Text))
        listaPatentesAsociadasUsuario = listaPatentesAsociadasUsuarioHeredadasPorFamilia
        'obtenemos la lista de patentes asociadas al usuario definitiva.
        'por cada patente otorgada recorro la lista de patentes heredadas por familia y si no está la agrego.
        'si ya estaba la patente heredada le fuerzo el estado permitido/denegado que esta dado por la patente otorgada.
        For Each pat1 As Patente_BE In listaPatentesAsociadasUsuarioOtorgadas
            existe = False
            For Each pat2 As Patente_BE In listaPatentesAsociadasUsuarioHeredadasPorFamilia
                If pat1.Id = pat2.Id Then
                    'seteo el estado de la patente otorgada.
                    pat2.Tipo = pat1.Tipo
                    existe = True
                    Exit For
                End If
            Next
            If existe = False Then
                'patente que no estaba heredada por nínguna familia -> la agrego.
                listaPatentesAsociadasUsuario.Add(pat1)
            End If
        Next

        'PATENTES DISPONIBLES.
        'resto a lista de todas las patentes del sistema, las que tengo heredadas por familia y otorgadas (nuevas o modifican tipo de las heredadas).
        ' me quedarán disponibles para asociar en algún momento.
        listaPatentesDisponibles = Patente_BL.ListarTodasLasPatentes
        For Each pat1 As Patente_BE In listaPatentesAsociadasUsuario
            'pregunto si ya esta en la lista de disponibles.
            For Each pat2 As Patente_BE In listaPatentesDisponibles
                If pat1.Id = pat2.Id Then
                    'la tengo asociada-> la descarto de las disponibles.
                    listaPatentesDisponibles.Remove(pat2)
                    Exit For
                End If
            Next
        Next

        ActualizarGrillasFamiliasPatentes()

    End Sub


    '<< PATENTE.
    Private Sub btnAsociarPatente_Click(sender As Object, e As EventArgs) Handles btnAsociarPatente.Click
        'control dgv vacío.
        If dgvPatentesDisponibles.RowCount = 0 Then
            MessageBox.Show("No hay patentes disponibles para otorgar a la lista de patentes asociadas..")
            Exit Sub
        End If

        'asignación detallada.
        Dim pat As New Patente_BE
        pat.Id = dgvPatentesDisponibles.SelectedRows(0).Cells(0).Value
        pat.Nombre = dgvPatentesDisponibles.SelectedRows(0).Cells(1).Value.ToString
        pat.Descripcion = dgvPatentesDisponibles.SelectedRows(0).Cells(2).Value.ToString
        pat.Tipo = CType(dgvPatentesDisponibles.SelectedRows(0).Cells(3).Value, Permisos)

        'guardamos la nueva relación en la tabla usuario_patente.
        Patente_BL.GuardarPatentePorUsuario(pat, CInt(Me.lbID.Text))

        listaPatentesAsociadasUsuario.Add(pat)
        'lo quito de la otra lista.
        Dim salir As Boolean = False
        For Each pat1 As Patente_BE In listaPatentesAsociadasUsuario
            For Each pat2 As Patente_BE In listaPatentesDisponibles
                If pat1.Id = pat2.Id Then
                    listaPatentesDisponibles.Remove(pat2)
                    salir = True
                    Exit For
                End If
            Next
            If salir = True Then
                Exit For
            End If
        Next
        ActualizarGrillasPatentes()

    End Sub


    '>> PATENTE.
    Private Sub btnDesasociarPatente_Click(sender As Object, e As EventArgs) Handles btnDesasociarPatente.Click
        'control dgv vacío.
        If dgvPatentesAsociadas.RowCount = 0 Then
            MessageBox.Show("No hay patentes asociadas para quitar..")
            Exit Sub
        End If

        'CONTROL no desasignar una patente heredada.
        'Tenemos en cuenta que una patente que pertenece a una familia asignada del usuario, no se puede desasignar atómaticamente (sólo se desasigna, quitándole al usuario la familia).
        'preguntamos si lo que estamos desasignando pertenece a una familia asignada.
        Dim listaPatentesDeLaFamilia As New List(Of Patente_BE)
        For Each familia As Familia_BE In listaFamiliasAsociadasUsuario
            'recorro de a una familia y tómo todas sus patentes.
            listaPatentesDeLaFamilia = Familia_BL.listarPatentesDeLaFamilia(familia.Id)
            'cada una de las patentes de la familia asociada, la comparo con la que quiero desasociar, si coincide, no se puede quitar..
            For Each pat1 As Patente_BE In listaPatentesDeLaFamilia
                If dgvPatentesAsociadas.SelectedRows(0).Cells(0).Value = pat1.Id Then
                    MessageBox.Show("esta patente es de una familia asociada del usuario, no se puede quitar.. sí se puede negar..")
                    Exit Sub
                End If
            Next
        Next

        'DESASIGNAR patente: el ciclo se completó y no la encontró en una familia asignada.
        'esta patente en algún momento se asigno de la lista de patentes disponibles (fuera de las familias asignadas)

        'desasignación detallada.
        Dim pat As New Patente_BE
        pat.Id = dgvPatentesAsociadas.SelectedRows(0).Cells(0).Value
        pat.Tipo = CType(dgvPatentesAsociadas.SelectedRows(0).Cells(1).Value, Permisos)
        pat.Nombre = dgvPatentesAsociadas.SelectedRows(0).Cells(2).Value.ToString
        pat.Descripcion = dgvPatentesAsociadas.SelectedRows(0).Cells(3).Value.ToString

        'quitamos la nueva relación en la tabla usuario_patente.
        Patente_BL.quitarPatentePorUsuario(pat, CInt(Me.lbID.Text))

        listaPatentesDisponibles.Add(pat)
        'lo quito de la otra lista.
        Dim salir As Boolean = False
        For Each pat1 As Patente_BE In listaPatentesDisponibles
            For Each pat2 As Patente_BE In listaPatentesAsociadasUsuario
                If pat1.Id = pat2.Id Then
                    listaPatentesAsociadasUsuario.Remove(pat2)
                    salir = True
                    Exit For
                End If
            Next
            If salir = True Then
                Exit For
            End If
        Next
        ActualizarGrillasPatentes()

    End Sub


    'patente permitida/negada.
    Private Sub btnCambiarEstadoPermiso_Click(sender As Object, e As EventArgs) Handles btnCambiarEstadoPermiso.Click

        'a la patente seleccionada le asigno el valor permitido o denegado, según el estado que se encuentre cuando presione Cambiar.
        For Each pat As Patente_BE In listaPatentesAsociadasUsuario
            If pat.Id = dgvPatentesAsociadas.SelectedRows(0).Cells(0).Value Then
                If Me.cbPatentePermitidaNegada.SelectedIndex = 0 Then
                    pat.Tipo = Patente_BE.Permisos.Denegado
                Else
                    pat.Tipo = Patente_BE.Permisos.Permitido
                End If
                'guardamos la nueva relación en la tabla usuario_patente.
                Patente_BL.GuardarPatentePorUsuario(pat, CInt(Me.lbID.Text))
            End If
        Next

        ActualizarGrillasPatentes()

    End Sub


    'salir.
    Private Sub btnSalir_Click(sender As Object, e As EventArgs) Handles btnSalir.Click
        Me.Close()
        Me.Dispose()
    End Sub


#End Region


#Region "Métodos Auxiliares"

    'click sobre la grilla de usuarios.
    Private Sub GrillaUsuarios_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles dgvUsuarios.Click
        'cargamos los textbox/labels/chboxs.
        Me.lbID.Text = Me.dgvUsuarios.SelectedRows(0).Cells(0).Value.ToString
        Me.cbIdioma.SelectedIndex = Me.dgvUsuarios.SelectedRows(0).Cells(1).Value
        Me.txtNombre.Text = Me.dgvUsuarios.SelectedRows(0).Cells(2).Value.ToString
        Me.txtApellido.Text = Me.dgvUsuarios.SelectedRows(0).Cells(3).Value.ToString
        Me.txtUsuario.Text = Me.dgvUsuarios.SelectedRows(0).Cells(4).Value.ToString
        Me.chbBloqueado.Checked = Me.dgvUsuarios.SelectedRows(0).Cells(6).Value
        Me.lbIntentosInc.Text = Me.dgvUsuarios.SelectedRows(0).Cells(7).Value.ToString
        Me.chbClaveBlanqueada.Checked = Me.dgvUsuarios.SelectedRows(0).Cells(8).Value
        Me.listaFamiliasAsociadasUsuario.Clear()
        Me.listaPatentesAsociadasUsuario.Clear()
    End Sub

    'actualizar grilla familia y patentes.
    Sub ActualizarGrillasFamiliasPatentes()

        'FAMILIAS.
        Me.dgvFamiliasDisponibles.Rows.Clear()
        For Each fam As Familia_BE In listaFamiliasDisponibles
            Me.dgvFamiliasDisponibles.Rows.Add(fam.Id, fam.Nombre, fam.Descripcion)
        Next

        Me.dgvFamiliasAsociadas.Rows.Clear()
        For Each fam As Familia_BE In listaFamiliasAsociadasUsuario
            Me.dgvFamiliasAsociadas.Rows.Add(fam.Id, fam.Nombre, fam.Descripcion)
        Next

        'PATENTES.  
        Me.dgvPatentesDisponibles.Rows.Clear()
        For Each pat1 As Patente_BE In listaPatentesDisponibles
            Me.dgvPatentesDisponibles.Rows.Add(pat1.Id, pat1.Nombre, pat1.Descripcion, CType(pat1.Tipo, Permisos))
        Next

        Me.dgvPatentesAsociadas.Rows.Clear()
        For Each pat2 As Patente_BE In listaPatentesAsociadasUsuario
            Me.dgvPatentesAsociadas.Rows.Add(pat2.Id, CType(pat2.Tipo, Permisos), pat2.Nombre, pat2.Descripcion)
        Next
        'cosmetica permitido/denegado en el DataGridView (lista patentes asociadas al usuario FINAL cargada).
        For Each rw As DataGridViewRow In dgvPatentesAsociadas.Rows
            If rw.Cells("c1").Value = 1 Then
                rw.Cells("c1").Style.BackColor = Color.DarkGreen
            Else
                rw.Cells("c1").Style.BackColor = Color.DarkRed
            End If
        Next

    End Sub

    'actualizar grilla patentes.
    Sub ActualizarGrillasPatentes()

        'PATENTES.
        Me.dgvPatentesDisponibles.Rows.Clear()
        For Each pat1 As Patente_BE In listaPatentesDisponibles
            Me.dgvPatentesDisponibles.Rows.Add(pat1.Id, pat1.Nombre, pat1.Descripcion, CType(pat1.Tipo, Permisos))
        Next

        Me.dgvPatentesAsociadas.Rows.Clear()
        For Each pat2 As Patente_BE In listaPatentesAsociadasUsuario
            Me.dgvPatentesAsociadas.Rows.Add(pat2.Id, CType(pat2.Tipo, Permisos), pat2.Nombre, pat2.Descripcion)
        Next
        'cosmetica permitido/denegado en el DataGridView (lista patentes asociadas al usuario FINAL cargada).
        For Each rw As DataGridViewRow In dgvPatentesAsociadas.Rows
            If rw.Cells("c1").Value = 1 Then
                rw.Cells("c1").Style.BackColor = Color.DarkGreen
            Else
                rw.Cells("c1").Style.BackColor = Color.DarkRed
            End If
        Next

    End Sub


    Private Sub frmGestionUsuarios_KeyDown(sender As Object, e As KeyEventArgs) Handles MyBase.KeyDown
        If e.KeyCode = Keys.F1 Then
            Help.ShowHelp(Me, Application.StartupPath & "\ayuda_SEAS.chm", "gestionusuarios.htm")
        End If
    End Sub


#End Region


End Class

